﻿/// ZaxControls
/// Programmed by Leland Ede
/// Website: http://www.zaxisstudios.com
/// E-Mail: codeplex@zaxis-studios.com
/// Create: 3/29/2014

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;

using ZaxLib.Web.Writers.Nodes;

namespace ZaxLib.Web.Writers
{
	public class JQWriter : IWriter
	{
		/// <summary>
		/// Container that hold code as it is added
		/// TODO: Figure out how to change this data structure around so that it can build a parent child relationship
		/// </summary>
		private ArrayList code;

		private INode _current = null;
        public INode Current
        {
            get
            {
                return _current;
            }
            set
            {
                _current = value;
            }
        }

		public JQWriter()
		{
			code = new ArrayList();
		}

		#region Child Methods

		public INode CreateTopNode()
		{
			Current = new JNode();
			Current.Top();
			code.Add(Current);

			return Current;
		}

		public INode CreateReadyFunction()
		{
			INode top = CreateTopNode();
			return CreateReadyFunction(Current);
		}

		public INode CreateReadyFunction(INode parent)
		{
			Current = parent;
			AddChild("document").Selector();
			AddChild("ready").Joined();
			return AddParam("function").Function();
		}

		public INode AddChild()
		{
			if (Current == null)
			{
				CreateTopNode();
			}

			return AddChild(Current);
		}

		public INode AddChild(INode parent)
		{
			INode node = new JNode(String.Empty);
			node.Parent = parent;
			parent.AddChild(node);

			return node;
		}

		public INode AddChild(String tok)
		{
			if (Current == null)
			{
				CreateTopNode();
			}
			INode node = AddChild(tok, Current);

			return node;
		}

		public INode AddChild(String tok, INode parent)
		{
			INode node = new JNode(tok);
			if (Current == null)
			{
				Current = parent;
			}

			node.Parent = parent;
			parent.AddChild(node);
			Current = node;

			return node;
		}

		public INode AddChild(String tok, String value)
		{
			if (Current == null)
			{
				Current = CreateTopNode();
			}
			return AddChild(tok, value, Current);
		}

		public INode AddChild(String tok, String value, INode parent)
		{
			INode node = new JNode(tok, value);
			if (Current == null)
			{
				Current = parent;
			}

			node.Parent = parent;
			parent.AddChild(node);
			Current = node;

			return node;
		}

		#endregion

		#region Parameter Methods

		public INode AddParam(String param)
		{
			if (Current == null)
			{
				CreateTopNode();
			}
			return AddParam(param, Current);
		}

		public INode AddParam(String param, INode parent)
		{
			INode node = new JNode(param);
			node.Type = NodeType.PARAMETER;
			if (Current == null)
			{
				Current = parent;
			}
			node.Parent = parent;
			parent.AddParam(node);

			return node;
			
		}

		public INode AddParam(String key, String value)
		{
			if (Current == null)
			{
				Current = CreateTopNode();
			}
			return AddParam(key, value, Current);
		}

		public INode AddParam(String key, String value, INode parent)
		{
			INode node = new JNode(key, value);
			node.Type = NodeType.PARAMETER;
			if (Current == null || Current != parent)
			{
				Current = parent;
			}
			node.Parent = parent;
			parent.AddParam(node);

			return node;
		}

		#endregion

		public void Write(HtmlTextWriter writer)
		{
			StringBuilder sb = new StringBuilder();
			// Check if there are any lines of code to render
			if (code.Count > 0)
			{
				writer.WriteLine();
				writer.AddAttribute(HtmlTextWriterAttribute.Type, "text/javascript");
				writer.RenderBeginTag(HtmlTextWriterTag.Script);
				// Loop through each line of code and add it to the output
				foreach (INode line in code)
				{

					sb.Append(line.Code);
				}

				writer.WriteLine(sb.ToString());
				writer.RenderEndTag();
				writer.Write("\n");
				writer.Flush();
			}
			Clear();
		}

		public void Clear()
		{
			Current = null;
			code.Clear();
		}
	}
}
